package com.jeeplus.modules.web.service;

import cn.hutool.core.lang.Dict;
import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.modules.web.entity.GetTotalVO;
import com.jeeplus.modules.web.entity.YJRoomUser;
import com.jeeplus.modules.web.entity.YjScoreRecord;
import com.jeeplus.modules.web.entity.wx.YsUser;
import com.jeeplus.modules.web.mapper.YJRoomUserMapper;
import com.jeeplus.modules.web.mapper.YjScoreRecordMapper;
import com.jeeplus.modules.web.socket.UserMsgSocket;
import com.jeeplus.modules.web.wx.YjScoreRecordController;
import org.javatuples.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 积分记录Service
 *
 * @author 十戒丶
 * @date 2021-01-21 21:31:21
 */
@Service
@Transactional(readOnly = true)
public class YjScoreRecordService extends CrudService<YjScoreRecordMapper, YjScoreRecord> {
    @Autowired
    private YjScoreRecordMapper yjScoreRecordMapper;
    @Autowired
    private YJRoomUserMapper yjRoomUserMapper;

    /**
     * 查询某个房间，某场牌局已保存的信息
     *
     * @param roomFlag
     * @param gamesCount
     */
    @Transactional(readOnly = false)
    public List<YjScoreRecord> findByRoomFlagAndGamesCount(String roomFlag, String gamesCount) {
        return yjScoreRecordMapper.findByRoomFlagAndGamesCount(roomFlag, gamesCount);
    }


    @Transactional(readOnly = false)
    public void save(YjScoreRecord yjScoreRecord) {
        super.save(yjScoreRecord);
    }

    @Transactional(readOnly = false)
    public void updateScoreInfo(YjScoreRecord yjScoreRecord) {
        yjScoreRecordMapper.updateScoreInfo(yjScoreRecord);
    }

    public List<YjScoreRecord> queryCurGamesNum(String roomFlag) {
        return yjScoreRecordMapper.queryCurGamesNum(roomFlag);
    }

    public Integer maxCurGamesNum(String roomFlag) {
        return yjScoreRecordMapper.maxCurGamesNum(roomFlag);
    }

    public AjaxJson test(String openId, String roomFlag, Integer pageSize, Integer pageNum) throws IOException {
        final Map<String, Pair<String, UserMsgSocket>> row = UserMsgSocket.webSocketTable.column(roomFlag);


        final String room = UserMsgSocket.webSocketTable.get(openId, roomFlag).getValue0();

        for (Pair<String, UserMsgSocket> value : row.values()) {
            final UserMsgSocket userMsgSocket = value.getValue1();
            userMsgSocket.session.getBasicRemote().sendText(new UserMsgSocket.ParamJson(UserMsgSocket.MsgCode.type_push.getValue0(), Dict.create().set("msg", "推送数据给你")).toJson());
        }
        final AjaxJson ajaxJson = new AjaxJson();
        ajaxJson.setMsg("触发测试");
        return ajaxJson;
    }

    @ResponseBody
    public GetTotalVO getTotal(String openId, String roomFlag, String roomNumber) {
        long start = System.currentTimeMillis();
        GetTotalVO getTotalVO = new GetTotalVO();
        //long jushustart = System.currentTimeMillis();
        //局数
        List<YjScoreRecord> gameCount = yjScoreRecordMapper.findCount(roomFlag, roomNumber, 0, 5);
        //long jushuEnd = System.currentTimeMillis();
        // logger.info("getTotal--获取局数总耗时："+(jushuEnd - jushustart) + "ms");

        // long taifeistart = System.currentTimeMillis();
        //台费
        List<YjScoreRecord> scoreRecordList = yjScoreRecordMapper.getCostTotal(roomFlag, roomNumber, 0, 5);
        //long taifeiend = System.currentTimeMillis();
        //logger.info("getTotal--获取每局台费总耗时："+(taifeiend - taifeistart) + "ms");

        //long zongtaifeistart = System.currentTimeMillis();
        List<YjScoreRecord> costList = yjScoreRecordMapper.getCostTotalByRoom(roomFlag, roomNumber);
        //long zongtaifeiend = System.currentTimeMillis();
        //logger.info("getTotal--获取总台费总耗时："+(zongtaifeiend - zongtaifeistart) + "ms");
        YJRoomUser yjRoomUser = new YJRoomUser();
        yjRoomUser.setRoomUser("台费");
        if (costList.get(0) != null && costList.size() > 0) {
            yjRoomUser.setTotalScore(costList.get(0).getGameCost());
        } else {
            yjRoomUser.setTotalScore("0");
        }
        if (scoreRecordList != null && scoreRecordList.size() > 0) {
            yjRoomUser.setList(gameCount);
        } else {
           /* YjScoreRecord yjScoreRecord = new YjScoreRecord();
            yjScoreRecord.set
            yjScoreRecord.setRemarks("");*/
            yjRoomUser.setList(new ArrayList<>());
        }

        //long renstart = System.currentTimeMillis();
        //人员
        List<YJRoomUser> roomUserList = yjRoomUserMapper.findUserByFlagAndNum(roomNumber, roomFlag);
        //long renend = System.currentTimeMillis();
        // logger.info("getTotal--获取每个房间人数总耗时："+(renend - renstart) + "ms");

        for (int index = 0, length = roomUserList.size(); index < length; index++) {
            if (openId.equals(roomUserList.get(index).getRoomUser())) {
                YJRoomUser temp = roomUserList.get(0);
                roomUserList.set(0, roomUserList.get(index));
                roomUserList.set(index, temp);
            }
        }

        //long mrenstart = System.currentTimeMillis();
        //获取每个人总分
        List<YjScoreRecord> totalUserList = yjScoreRecordMapper.scoreTotal(roomFlag, roomNumber);
        //long mrenend = System.currentTimeMillis();
        // logger.info("getTotal--获取每个人总分总耗时："+(mrenend - mrenstart) + "ms");
        //局数
        List<YjScoreRecord> gameCountList = new ArrayList<>();
        //yjScoreRecordMapper.getCostTotal(roomFlag, roomNumber);
        if (scoreRecordList.size() > 0) {
            //取五条
            gameCountList = scoreRecordList.subList(0, Math.min(scoreRecordList.size(), 5));
        }
        //long mrenmeijustart = System.currentTimeMillis();
        for (YJRoomUser user : roomUserList) {
            if (totalUserList.size() > 0) {
                boolean bool = totalUserList.stream().anyMatch(a -> a.getRoomUser().equals(user.getRoomUser()));
                if (bool) {
                    for (YjScoreRecord record : totalUserList) {
                        if (record.getRoomUser().equals(user.getRoomUser())) {
                            user.setTotalScore(record.getScore());
                        }
                    }
                } else {
                    user.setTotalScore("0");
                }


                //获取每人所有局分数
                List<YjScoreRecord> userRecordList = yjScoreRecordMapper.getScoreDetail(user.getRoomFlag(), user.getRoomNum(), user.getRoomUser(), "", 0, 5);

                List<YjScoreRecord> scoreUList = new ArrayList<>();
                for (YjScoreRecord record : gameCountList) {
                    //获取每人每局对应分数
                    List<YjScoreRecord> scoreUserList = userRecordList.stream().filter(userRecord -> userRecord.getGamesCount().equals(record.getGamesCount())).collect(Collectors.toList());
                    // yjScoreRecordMapper.getScoreDetail(user.getRoomFlag(), user.getRoomNum(), user.getRoomUser(), record.getGamesCount());

                    if (scoreUserList.size() > 0) {
                        scoreUList.add(scoreUserList.get(0));
                    } else {
                        YjScoreRecord recordw = new YjScoreRecord();
                        recordw.setRoomNum(user.getRoomNum());
                        recordw.setGamesCount(record.getGamesCount());
                        recordw.setScore("0");
                        recordw.setRoomUser(user.getRoomUser());
                        recordw.setRoomFlag(user.getRoomFlag());
                        scoreUList.add(recordw);
                    }
                }
                user.setList(scoreUList);

            } else {
                user.setList(new ArrayList<>());
                user.setTotalScore("0");
            }
            user.getList().stream().sorted(Comparator.comparing(YjScoreRecord::getGamesCount))
                    .collect(Collectors.toList());
        }
        //long mrenmeijuend = System.currentTimeMillis();
        //logger.info("getTotal--获取每个人每局分数总耗时："+(mrenmeijuend - mrenmeijustart) + "ms");
        //final LinkedHashMap<String, Object> map = Maps.newLinkedHashMap();;


        if (roomUserList.size() > 0) {
            getTotalVO.setGameCount(gameCount);
            getTotalVO.setGameCost(yjRoomUser);
            getTotalVO.setSuccess(true);
            getTotalVO.setUser(roomUserList);
            //map.put("gameCount", gameCount);
            //map.put("gameCost", yjRoomUser);
            //map.put("success", true);
            //map.put("user", roomUserList);
        } else {
            getTotalVO.setSuccess(false);
            getTotalVO.setList(scoreRecordList);
            //map.put("success", false);
            //map.put("list", scoreRecordList);
        }
        long end = System.currentTimeMillis();
        logger.info("getTotal--获取每人分数统计总耗时：" + (end - start) + "ms");

        return getTotalVO;
    }

    /**
     * @param helpNotesId
     * @param openId
     * @param roomFlag
     * @param type        true新增，false删除
     */
    public void socketPutHelpRecord(String helpNotesId, String openId, String roomFlag, boolean type) throws IOException {
        AjaxJson ajaxJson = new AjaxJson();
        //发送帮记helpNotesId,提示有帮记
        final LinkedHashMap<String, Object> linkedHashMap = Maps.newLinkedHashMap();
        List<YsUser> ysUserList = new ArrayList<>();
        List<Table<String, YsUser, Integer>> removeList = new ArrayList<>();
        final List<Table<String, YsUser, Integer>> pairList = YjScoreRecordController.helpNotesCache.get(Pair.with(helpNotesId, roomFlag));
        if (pairList != null && !pairList.isEmpty()) {
            final Optional<Table<String, YsUser, Integer>> any = pairList.stream().filter(v -> v.rowKeySet().contains(openId)).findAny();
            if (any.isPresent()) {
                if (type) {
                    ysUserList.add(any.get().row(openId).keySet().stream().findFirst().orElse(null));
                } else {
                    removeList.add(any.get());
                }
            }
            pairList.removeAll(removeList);
            linkedHashMap.put("users", ysUserList);
            linkedHashMap.put("removeUsers", removeList.stream().map(v1 -> v1.row(v1.rowKeySet().stream().findFirst().orElse(null)).keySet().stream().findFirst().orElse(null)).collect(Collectors.toList()));
        }
        ajaxJson.setBody(linkedHashMap);
        ajaxJson.setSuccess(true);
        ajaxJson.setMsg("帮记推送");
        UserMsgSocket.webSocketTable.get(helpNotesId, roomFlag).getValue1().session.getBasicRemote().sendText(new UserMsgSocket.ParamJson(UserMsgSocket.MsgCode.type_help_record.getValue0(), ajaxJson).toJson());
    }

    public void socketPutNextGame(String openId, String roomFlag, int gamesCount) throws IOException {
        final Map<String, Pair<String, UserMsgSocket>> column = UserMsgSocket.webSocketTable.column(roomFlag);
        AjaxJson ajaxJson = new AjaxJson();
        final LinkedHashMap<String, Object> linkedHashMap = Maps.newLinkedHashMap();
        linkedHashMap.put("gamesCount", gamesCount);
        ajaxJson.setSuccess(true);
        ajaxJson.setMsg("对局推送");
        ajaxJson.setBody(linkedHashMap);
        for (String v : column.keySet()) {
            try {
                column.get(v).getValue1().session.getBasicRemote().sendText(new UserMsgSocket.ParamJson(UserMsgSocket.MsgCode.type_next_game.getValue0(), ajaxJson).toJson());
            } catch (Exception exception) {
                logger.error("socketPutNextGame异常：", exception);
            }
        }
    }
}
